import * as XLSX from 'xlsx'
import FileSaver from 'file-saver'
// storage-start
import * as $CONST from './constant'
import { ElMessage, ElNotification  } from 'element-plus'
import { getLocal } from '@/utils/navigation'
import dayjs from 'dayjs'
import * as _ from 'lodash';

// 获取国家列表
export const getCountryName = (arr, code) => {
  let resultArr = arr.filter((item) => item['canonical_country_code'] === code)
  return resultArr[0] ? resultArr[0]['country_name_en'] : ''
}

export const notice = (errno, errmsg) => {
  if (errno == 0) {
    ElNotification ({
      title: 'success',
      message: 'handle success',
      type: 'success',
      dangerouslyUseHTMLString: true,
    })
  } else {
    ElNotification ({
      title: 'error',
      message: errmsg,
      duration: 0,
      type: 'error',
      dangerouslyUseHTMLString: true,
    })
  }
}

export const dynamicPageSize = () => {
  let result = 10
  try {
    let height = window.innerHeight
    let pageSize = parseInt(height / 45 - 2)
    let paramPre = _.round(pageSize / 100, 1) * 100
    if (paramPre <= 0) {
      result = 10
    } else if (paramPre >= 100) {
      result = 100
    } else {
      result = paramPre
    }
  } catch (e) {
    result = 10
  }
  return result
}

export const messageFeature = (errno, errmsg) => {
  if (errno == 0) {
    ElNotification ({
      title: 'success',
      message: errmsg,
      type: 'success',
      dangerouslyUseHTMLString: true,
    })
  }
}

/**
 * 集合转换为JSON
 * @param obj collection数据
 * @author TJ 2019/03/11
 * @example 略
 */
export function collectionToJson(collection) {
  if (!_.isArray(collection)) return []
  let arr = []
  // 数据体
  _.forEach(collection, function (item) {
    let tempObj = {}
    if (item.hasOwnProperty('data') && _.isArray(item.data)) {
      _.forEach(item.data, function (obj) {
        tempObj[_.trim(obj.name)] = _.trim(obj.value)
      })
    }
    arr.push(tempObj)
  })
  return arr
}

/**
 * collection数据转换为标准JSON
 * @param obj collection数据
 * @author TJ 2019/03/11
 * @example 略
 */
export function transformStandardJson(obj) {
  let body = {}
  let data = null
  let pages = null
  let collection = obj.collection
  if (_.isObject(collection)) {
    // 错误的场景
    if (collection.hasOwnProperty('error')) {
      return {
        code: 300,
        body: null,
        msg: collection.error,
      }
    }
    // 数据体
    if (collection.hasOwnProperty('items') && _.isArray(collection.items)) {
      data = collectionToJson(collection.items)
    }
    // 分页信息
    if (collection.hasOwnProperty('page') && _.isArray(collection.data)) {
      pages = collectionToJson([collection.page])
    }
    // 组装body数据
    body = {
      data: data,
    }

    if (pages) {
      _.extend(body, {
        total: pages[0].totalElements,
        pageIndex: 0,
        pageSize: pages[0].size,
        pages: pages[0].totalPages,
      })
    }

    return {
      code: 200,
      body: body,
      msg: '操作成功',
    }
  }
}

/**
 * POST PUT等请求参数转换成集合
 * @param json object
 * @returns collection
 * @author TJ 2019/03/11
 * @example 略
 */
export function transformParams(obj) {
  let collection = {
    version: '1.0',
    href: '',
    items: [],
    templates: [],
  }
  if (_.isObject(obj)) {
    let arr = []
    _.each(obj, function (val, key) {
      let newVal = val
      if (_.isArray(val)) {
        newVal = val.join(',')
      }
      arr.push({
        name: key,
        value: newVal,
      })
    })

    let o = {
      data: arr,
    }
    collection.templates.push(o)
  }
  return {
    collection: collection,
  }
}

/**
 * 将内容存储到sessionStorage
 * @param key {string} key
 * @param content {Object} 存储json对象
 * @author TJ 2018/05/28
 * @example 略
 */
export function setSessionStorage(key, content) {
  if (!key) return false
  let jsonContent = JSON.stringify(content)
  jsonContent
    ? sessionStorage.setItem(key, jsonContent)
    : sessionStorage.setItem(key, content)
}

/**
 * 获取存储到sessionStorage的内容
 * @param key {string} key
 * @return {object} 返回json对象
 * @author TJ 2018/05/28
 * @example 略
 */
export function getSessionStorage(key) {
  let item = sessionStorage.getItem(key)
  if (!item) return false
  let result = JSON.parse(sessionStorage.getItem(key))
  return result ? result : item
}

/**
 * 删除存储到sessionStorage的内容
 * @param key {string} key
 * @author TJ 2018/05/28
 * @example 略
 */
export function removeSessionStorage(key) {
  sessionStorage.removeItem(key)
}

/**
 * 将内容存储到localStorage
 * @param key {string} key
 * @param content {Object} 存储json对象
 * @author TJ 2018/05/28
 * @example 略
 */
export function setLocalStorage(key, content) {
  if (!key) return false
  let jsonContent = JSON.stringify(content)
  jsonContent
    ? localStorage.setItem(key, jsonContent)
    : localStorage.setItem(key, content)
}

/**
 * 获取存储到localStorage的内容
 * @param key {string} key
 * @return {object} 返回json对象
 * @author TJ 2018/05/28
 * @example 略
 */
export function getLocalStorage(key) {
  let item = localStorage.getItem(key)
  if (!item) return false
  let result = JSON.parse(localStorage.getItem(key))
  return result ? result : item
}

/**
 * localStorage
 * @param key {string} key
 * @author TJ 2018/05/28
 * @example 略
 */
export function removeLocalStorage(key) {
  localStorage.removeItem(key)
}

/**
 * 判断json对象是否为空对象
 * @param obj {object} json对象
 * @return {boolean} 空对象返回 true 否则返回 false
 * @author TJ 2018/05/28
 * @example 略
 */
export function isEmptyObject(obj) {
  try {
    if (obj === null) return true
    return Object.keys(obj).length === 0
  } catch (e) {
    return true
  }
}
/**
 * 过滤参数
 * @param params {object} 需要格式化的时间
 * @return {object} 格式化后的时间
 * @author TJ 2017/05/28
 * @example 略
 */
export function filterParams(params) {
  if (!_.isObject(params)) {
    return params
  }
  let newParams = {}
  _.each(params, function (v, k) {
    // 过滤掉条件是空的项
    newParams[k] = v
    // if (typeof v === 'string' && (v.length === 0 || v === '*全*部*')) {
    // } else {
    //   newParams[k] = v
    // }
  })
  return newParams
}

export function clearParam(params) {
  if (!_.isObject(params)) {
    return params
  }
  let newParams = {}
  _.each(params, function (v, k) {
    // 过滤掉条件是空的项
    if (isTrue(v)) {
      newParams[k] = v
    }
    // if (typeof v === 'string' && (v.length === 0 || v === '*全*部*')) {
    // } else {
    //   newParams[k] = v
    // }
  })
  return newParams
}

/**
 * 将null转换为空对象
 * @param params {obj}
 * @author TJ 2018/05/31
 */
export function emptyObjectWrapper(obj) {
  return obj === null ? {} : obj
}

/**
 * 格式化时间
 * @param time {string} 需要格式化的时间
 * @param cFormat {string} 时间格式
 * @return {string} 格式化后的时间
 * @author TJ 2017/07/21
 * @example 略
 */
export function parseTime(time, cFormat) {
  if (!time) return false
  if (arguments.length === 0) {
    return false
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if (('' + time).length === 10) time = parseInt(time) * 1000
    if (
      ('' + time).length === 8 &&
      ('' + time).indexOf('-') === -1 &&
      ('' + time).indexOf('/') === -1
    ) {
      time =
        time.substring(0, 4) +
        '-' +
        time.substring(4, 6) +
        '-' +
        time.substring(6, 8)
    }

    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay(),
  }
  const timeStr = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
    let value = formatObj[key]
    if (key === 'a')
      return ['一', '二', '三', '四', '五', '六', '日'][value - 1]
    if (result.length > 0 && value < 10) {
      value = '0' + value
    }
    return value || 0
  })
  return timeStr
}

/**
 * 将时间数组分割成开始时间和结束时间
 * @param time {array}
 * @return {object}
 * @author TJ 2017/08/01
 * @example 略
 */
export function formatTime(time) {
  if (Array.isArray(time)) {
    if (!time[0] || !time[1]) return false
    var start = parseTime(time[0], '{y}-{m}-{d}')
    var end = parseTime(time[1], '{y}-{m}-{d}')
    return {
      start: start,
      end: end,
    }
  }

  return false
}

/**
 * 权限API拼接用户名
 * @param api {String}
 * @return {boolean}
 * @author TJ 2017/08/01
 * @example 略
 */
export function getJoinOauthApi(url) {
  let name = window._loginName ? window._loginName : ''
  if (url.includes('?')) {
    url += '&createId=' + name
  } else {
    url += 'createId=' + name
  }
  return url
}

/**
 * 拼接查询URL
 * @param url {String}
 * @param obj {obj}
 * @return {String}
 * @author TJ 2017/08/01
 * @example 略
 */
export function joinQueryUrl(url, obj) {
  let str = ''
  let fullUrl = ''
  for (let key in obj) {
    if (key) {
      if (!obj.hasOwnProperty(key)) return
      if (str) {
        str += '&'
      }
      str += key + '=' + obj[key]
    }
  }
  if (url.includes('?')) {
    fullUrl = url + '&' + str
  } else {
    fullUrl = url + '?' + str
  }
  return fullUrl
}

/**
 * 判断参数是否嵌入在url中
 * @param url {String}
 * @return {Boolean}
 * @author TJ 2018/08/27
 */
export function isInlineParams(url) {
  try {
    const splitChar = '{$'
    if (url && url.indexOf(splitChar) > -1) {
      return true
    } else {
      return false
    }
  } catch (e) {
    return false
  }
}

/**
 * 替换url里的参数
 * match
 * @param url {String}
 * @param params {obj}
 * @author TJ 2018/05/31
 */
export function replaceUrlParams(url, params) {
  if (url) {
    if (!isInlineParams(url)) {
      return url
    }
    // 正则匹配{}，生成数组
    let patt = /\{.*?\}/g
    let arr = url.match(patt) ? url.match(patt) : []
    arr.forEach(function (item) {
      let key = item.replace('{', '').replace('}', '').replace('$', '')
      url = url.replace(item, params[key])
    })
  }
  return url
}

// 为dom添加拖拽功能
export function addDrag(id) {
  let drag = document.getElementById(id)
  if (!drag) return
  // //点击某物体时，用drag对象即可，move和up是全局区域，
  // 也就是整个文档通用，应该使用document对象而不是drag对象(否则，采用drag对象时物体只能往右方或下方移动)
  // let event = event || window.event // 兼容IE浏览器
  drag.onmousedown = function (event) {
    //    鼠标点击物体那一刻相对于物体左侧边框的距离=点击时的位置相对于浏览器最左边的距离-物体左边框相对于浏览器最左边的距离
    let diffX = event.clientX - drag.offsetLeft
    let diffY = event.clientY - drag.offsetTop
    if (typeof drag.setCapture !== 'undefined') {
      drag.setCapture()
    }
    document.onmousemove = function (event) {
      // let event = event || window.event
      let moveX = event.clientX - diffX
      let moveY = event.clientY - diffY
      drag.style.left = moveX + 'px'
      drag.style.top = moveY + 'px'
    }
    document.onmouseup = function (event) {
      this.onmousemove = null
      this.onmouseup = null
      // 修复低版本ie bug
      if (typeof drag.releaseCapture !== 'undefined') {
        drag.releaseCapture()
      }
    }
  }
}

// 判断浏览器类型
export const getBrowserType = () => {
  let userAgent = navigator.userAgent //取得浏览器的userAgent字符串
  let browser = 'unknown'
  if (userAgent.indexOf('IE') != -1) {
    //字符串含有IE字段，表明是IE浏览器
    browser = 'IE'
  } else if (userAgent.indexOf('Firefox') != -1) {
    //字符串含有Firefox字段，表明是火狐浏览器
    browser = 'Firefox'
  } else if (userAgent.indexOf('OPR') != -1) {
    //Opera
    browser = 'Opera'
  } else if (userAgent.indexOf('Chrome') != -1) {
    //Chrome
    browser = 'Chrome'
  } else if (userAgent.indexOf('Safari') != -1) {
    //Safari
    browser = 'Safari'
  } else if (userAgent.indexOf('Trident') != -1) {
    //IE内核
    browser = 'IE 11'
  }
  return browser
}

/**
 * 获取传入小时之前的日期
 * @param pastHour {Number}
 * @param format {String}
 * @author ZC 2020/11/03
 */
export function zcGetDate(pastHour, format) {
  if (!format) {
    format = 'yyyy-MM-dd'
  }
  // eslint-disable-next-line no-extend-native
  Date.prototype.Format = function (fmt) {
    let o = {
      'M+': this.getMonth() + 1, // 月份
      'd+': this.getDate(), // 日
      'h+': this.getHours(), // 小时
      'm+': this.getMinutes(), // 分
      's+': this.getSeconds(), // 秒
      'q+': Math.floor((this.getMonth() + 3) / 3), // 季度
      S: this.getMilliseconds(), // 毫秒
    }
    if (/(y+)/.test(fmt))
      fmt = fmt.replace(
        RegExp.$1,
        (this.getFullYear() + '').substr(4 - RegExp.$1.length)
      )
    for (let k in o) {
      // eslint-disable-next-line eqeqeq
      if (new RegExp('(' + k + ')').test(fmt))
        fmt = fmt.replace(
          RegExp.$1,
          RegExp.$1.length == 1
            ? o[k]
            : ('00' + o[k]).substr(('' + o[k]).length)
        )
    }
    return fmt
  }
  if (pastHour) {
    // 获取之前的时间
    return new Date(new Date().getTime() - pastHour * 60 * 60 * 1000).Format(
      format
    )
  } else {
    return new Date(new Date().getTime()).Format(format)
  }
}

/**
 * 获取传入时间一周的数据
 */
export const zcGetWeek = (date, pastHour, isDay) => {
  if (!isTrue(isDay)) {
    isDay = false
  }
  // eslint-disable-next-line no-extend-native
  Date.prototype.Format = function (fmt) {
    let o = {
      'M+': this.getMonth() + 1, // 月份
      'd+': this.getDate(), // 日
      'h+': this.getHours(), // 小时
      'm+': this.getMinutes(), // 分
      's+': this.getSeconds(), // 秒
      'q+': Math.floor((this.getMonth() + 3) / 3), // 季度
      S: this.getMilliseconds(), // 毫秒
    }
    if (/(y+)/.test(fmt))
      fmt = fmt.replace(
        RegExp.$1,
        (this.getFullYear() + '').substr(4 - RegExp.$1.length)
      )
    for (let k in o) {
      // eslint-disable-next-line eqeqeq
      if (new RegExp('(' + k + ')').test(fmt))
        fmt = fmt.replace(
          RegExp.$1,
          RegExp.$1.length == 1
            ? o[k]
            : ('00' + o[k]).substr(('' + o[k]).length)
        )
    }
    return fmt
  }
  if (isDay) {
    return new Date(
      Date.parse(new Date(date)) + pastHour * 60 * 60 * 1000
    ).Format('yyyy-MM-dd')
  } else {
    return new Date(
      Date.parse(new Date(date)) + pastHour * 60 * 60 * 1000
    ).Format('yyyy-MM-dd 00:00:00')
  }
}

/**
 * 获取周一的日期
 */
export function getFirstDayOfWeek(date, isDay) {
  if (!isTrue(isDay)) {
    isDay = false
  }
  let weekday = date.getDay() || 7 // 获取星期几,getDay()返回值是 0（周日） 到 6（周六） 之间的一个整数。0||7为7，即weekday的值为1-7
  date.setDate(date.getDate() - weekday + 1) // 往前算（weekday-1）天，年份、月份会自动变化
  if (isDay) {
    return parseTime(date, '{y}-{m}-{d}')
  } else {
    return parseTime(date, '{y}-{m}-{d}') + ' 00:00:00'
  }
}

/**
 * 下载方法
 */
export const fileDownLoad = (url, fileName) => {
  let downloadElement = document.createElement('a')
  downloadElement.href = url
  downloadElement.target = '_blank' // 创建
  if (isTrue(fileName)) {
    downloadElement.download = fileName
  } else {
    downloadElement.download = url.substring(
      url.lastIndexOf('/') + 1,
      url.length
    ) // 下载后文件名
  }
  document.body.appendChild(downloadElement)
  downloadElement.click() // 点击下载
  document.body.removeChild(downloadElement) // 下载完成移除元素
}

// 复制文字方法
export const copyText = (content) => {
  // 创建textArea
  let textA = document.createElement('textarea')
  textA.id = 'copyArea'
  textA.value = content
  document.body.appendChild(textA)
  try {
    textA.select()
    document.execCommand('Copy')
    document.body.removeChild(textA) // 下载完成移除元素
    ElMessage({
      type: 'success',
      message: 'copy success',
      center: true,
    })
  } catch (error) {
    this.$message({
      type: 'error',
      message: `Your browser don't support this operation`,
      center: true,
    })
  }
}
/**
 * 配置Echart主题颜色
 * @param {obj} echart 实例
 * @author TJ 2017/10/17
 * @return 无返回结果
 */
export function resgisterTheme(echart) {
  /* eslint-disable */
  let theme = {
    color: [
      '#29d0b0',
      '#2d99ed',
      '#fd8667',
      '#72ccff',
      '#f7c5a0',
      '#d4a4eb',
      '#fdc547',
      '#76f2f2',
      '#da4d00',
      '#b0419e',
    ],
    backgroundColor: 'transparents',
    textStyle: {
      itemStyle: {
        normal: {
          color: '#fff',
        },
      },
    },
    title: {
      textStyle: {
        color: '#ffffff',
      },
      subtextStyle: {
        color: '#dddddd',
      },
    },
    line: {
      itemStyle: {
        normal: {
          borderWidth: '1',
        },
      },
      lineStyle: {
        normal: {
          width: '1',
        },
      },
      symbolSize: '4',
      symbol: 'circle',
      smooth: false,
    },
    radar: {
      itemStyle: {
        normal: {
          borderWidth: '4',
        },
      },
      lineStyle: {
        normal: {
          width: '3',
        },
      },
      symbolSize: '1',
      symbol: 'circle',
      smooth: true,
    },
    bar: {
      itemStyle: {
        normal: {
          barBorderWidth: 0,
          barBorderColor: '#ccc',
        },
        emphasis: {
          barBorderWidth: 0,
          barBorderColor: '#ccc',
        },
      },
    },
    pie: {
      itemStyle: {
        normal: {
          borderWidth: 0,
          borderColor: '#ccc',
        },
        emphasis: {
          borderWidth: 0,
          borderColor: '#ccc',
        },
      },
    },
    scatter: {
      itemStyle: {
        normal: {
          borderWidth: 0,
          borderColor: '#ccc',
        },
        emphasis: {
          borderWidth: 0,
          borderColor: '#ccc',
        },
      },
    },
    boxplot: {
      itemStyle: {
        normal: {
          borderWidth: 0,
          borderColor: '#ccc',
        },
        emphasis: {
          borderWidth: 0,
          borderColor: '#ccc',
        },
      },
    },
    parallel: {
      itemStyle: {
        normal: {
          borderWidth: 0,
          borderColor: '#ccc',
        },
        emphasis: {
          borderWidth: 0,
          borderColor: '#ccc',
        },
      },
    },
    sankey: {
      itemStyle: {
        normal: {
          borderWidth: 0,
          borderColor: '#ccc',
        },
        emphasis: {
          borderWidth: 0,
          borderColor: '#ccc',
        },
      },
    },
    funnel: {
      itemStyle: {
        normal: {
          borderWidth: 0,
          borderColor: '#ccc',
        },
        emphasis: {
          borderWidth: 0,
          borderColor: '#ccc',
        },
      },
    },
    gauge: {
      itemStyle: {
        normal: {
          borderWidth: 1,
          borderColor: '#fff',
        },
        emphasis: {
          borderWidth: 1,
          borderColor: '#fff',
        },
      },
    },
    candlestick: {
      itemStyle: {
        normal: {
          color: '#fc97af',
          color0: 'transparent',
          borderColor: '#fc97af',
          borderColor0: '#87f7cf',
          borderWidth: '2',
        },
      },
    },
    graph: {
      itemStyle: {
        normal: {
          borderWidth: 0,
          borderColor: '#ccc',
        },
      },
      lineStyle: {
        normal: {
          width: '1',
          color: '#ffffff',
        },
      },
      symbolSize: '5',
      symbol: 'circle',
      smooth: true,
      color: [
        '#29d0b0',
        '#2d99ed',
        '#fd8667',
        '#72ccff',
        '#f7c5a0',
        '#d4a4eb',
        '#fdc547',
        '#76f2f2',
        '#da4d00',
        '#b0419e',
      ],
      label: {
        normal: {
          textStyle: {
            color: '#293441',
          },
        },
      },
    },
    map: {
      itemStyle: {
        normal: {
          areaColor: '#f3f3f3',
          borderColor: '#999999',
          borderWidth: 0.5,
        },
        emphasis: {
          areaColor: 'rgba(255,178,72,1)',
          borderColor: '#eb8146',
          borderWidth: 1,
        },
      },
      label: {
        normal: {
          textStyle: {
            color: '#893448',
          },
        },
        emphasis: {
          textStyle: {
            color: 'rgb(137,52,72)',
          },
        },
      },
    },
    geo: {
      itemStyle: {
        normal: {
          areaColor: '#f3f3f3',
          borderColor: '#999999',
          borderWidth: 0.5,
        },
        emphasis: {
          areaColor: 'rgba(255,178,72,1)',
          borderColor: '#eb8146',
          borderWidth: 1,
        },
      },
      label: {
        normal: {
          textStyle: {
            color: '#893448',
          },
        },
        emphasis: {
          textStyle: {
            color: 'rgb(137,52,72)',
          },
        },
      },
    },
    categoryAxis: {
      axisLine: {
        show: true,
        lineStyle: {
          color: '#fff',
        },
      },
      axisTick: {
        show: false,
        lineStyle: {
          color: '#fff',
        },
      },
      axisLabel: {
        show: true,
        textStyle: {
          color: '#fff',
        },
      },
      splitLine: {
        show: false,
        lineStyle: {
          color: ['#e6e6e6'],
        },
      },
      splitArea: {
        show: false,
        areaStyle: {
          color: ['rgba(250,250,250,0.05)', 'rgba(200,200,200,0.02)'],
        },
      },
    },
    valueAxis: {
      axisLine: {
        show: true,
        lineStyle: {
          color: '#fff',
        },
      },
      axisTick: {
        show: false,
        lineStyle: {
          color: '#fff',
        },
      },
      axisLabel: {
        show: true,
        textStyle: {
          color: '#fff',
        },
      },
      splitLine: {
        show: false,
        lineStyle: {
          color: ['#e6e6e6'],
        },
      },
      splitArea: {
        show: false,
        areaStyle: {
          color: ['rgba(250,250,250,0.05)', 'rgba(200,200,200,0.02)'],
        },
      },
    },
    logAxis: {
      axisLine: {
        show: true,
        lineStyle: {
          color: '#fff',
        },
      },
      axisTick: {
        show: false,
        lineStyle: {
          color: '#333',
        },
      },
      axisLabel: {
        show: true,
        textStyle: {
          color: '#fff',
        },
      },
      splitLine: {
        show: false,
        lineStyle: {
          color: ['#e6e6e6'],
        },
      },
      splitArea: {
        show: false,
        areaStyle: {
          color: ['rgba(250,250,250,0.05)', 'rgba(200,200,200,0.02)'],
        },
      },
    },
    timeAxis: {
      axisLine: {
        show: true,
        lineStyle: {
          color: '#fff',
        },
      },
      axisTick: {
        show: false,
        lineStyle: {
          color: '#fff',
        },
      },
      axisLabel: {
        show: true,
        textStyle: {
          color: '#fff',
        },
      },
      splitLine: {
        show: false,
        lineStyle: {
          color: ['#fff'],
        },
      },
      splitArea: {
        show: false,
        areaStyle: {
          color: ['rgba(250,250,250,0.05)', 'rgba(200,200,200,0.02)'],
        },
      },
    },
    toolbox: {
      iconStyle: {
        normal: {
          borderColor: '#999999',
        },
        emphasis: {
          borderColor: '#666666',
        },
      },
    },
    legend: {
      textStyle: {
        color: '#e0e0e0',
      },
    },
    tooltip: {
      axisPointer: {
        lineStyle: {
          color: '#cccccc',
          width: 1,
        },
        crossStyle: {
          color: '#cccccc',
          width: 1,
        },
      },
    },
    timeline: {
      lineStyle: {
        color: '#87f7cf',
        width: 1,
      },
      itemStyle: {
        normal: {
          color: '#87f7cf',
          borderWidth: 1,
        },
        emphasis: {
          color: '#f7f494',
        },
      },
      controlStyle: {
        normal: {
          color: '#87f7cf',
          borderColor: '#87f7cf',
          borderWidth: 0.5,
        },
        emphasis: {
          color: '#87f7cf',
          borderColor: '#87f7cf',
          borderWidth: 0.5,
        },
      },
      checkpointStyle: {
        color: '#fc97af',
        borderColor: 'rgba(252,151,175,0.3)',
      },
      label: {
        normal: {
          textStyle: {
            color: '#87f7cf',
          },
        },
        emphasis: {
          textStyle: {
            color: '#87f7cf',
          },
        },
      },
    },
    visualMap: {
      color: ['#fc97af', '#87f7cf'],
    },
    dataZoom: {
      backgroundColor: 'rgba(255,255,255,0)',
      dataBackgroundColor: 'rgba(114,204,255,1)',
      fillerColor: 'rgba(114,204,255,0.2)',
      handleColor: '#72ccff',
      handleSize: '100%',
      textStyle: {
        color: '#fff',
      },
    },
    markPoint: {
      label: {
        normal: {
          textStyle: {
            color: '#293441',
          },
        },
        emphasis: {
          textStyle: {
            color: '#293441',
          },
        },
      },
    },
  }
  echart.registerTheme('dark', theme)
  /* eslint-enable */
}

/**
 * 根据路由切换皮肤标识，默认皮肤未蓝色
 * @author TJ 2019/05/29
 */
export function changeThemeClass(toRouterName) {
  const darkSkinRouterName = []

  if (darkSkinRouterName.includes(toRouterName)) {
    document.body.className = 'dark'
  } else {
    document.body.className = 'blue'
  }
}

/**
 * 判断要查询的数组是否至少有一个元素包含在目标数组中
 * @param {Array} target 目标数组
 * @param {Array} arr 需要查询的数组
 */
export const hasOneOf = (targetarr, arr) => {
  return targetarr.some((_) => arr.indexOf(_) > -1)
}

/**
 * 判断两个对象是否相等，这两个对象的值只能是数字或字符串
 * @param {Object} obj1 对象
 * @param {Object} obj2 对象
 */
export const objEqual = (obj1, obj2) => {
  const keysArr1 = Object.keys(obj1)
  const keysArr2 = Object.keys(obj2)
  if (keysArr1.length !== keysArr2.length) return false
  else if (keysArr1.length === 0 && keysArr2.length === 0) return true
  /* eslint-disable-next-line */ else
    return !keysArr1.some((key) => obj1[key] != obj2[key])
}

/**
 * 判断值是否为真,不包括对0的判断
 * @param {String} val 字符
 */
export function isTrue(val) {
  try {
    return !_.isNull(val) && !_.isUndefined(val) && val !== ''
  } catch (e) {
    return false
  }
}

/**
 * 解析URL参数
 *
 * @param {String} url
 * @return {object}
 */
export function getQueryObject(url = window.location.href) {
  if (!url) return
  let search = url.substring(url.lastIndexOf('?') + 1)
  let obj = {}
  let reg = /([^?&=]+)=([^?&=]*)/g
  search.replace(reg, function (rs, $1, $2) {
    let name = decodeURIComponent($1)
    let val = decodeURIComponent($2)
    val = String(val)
    obj[name] = val
    // return rs
  })
  return obj
}

/**
 * 根据不同的协议，替换env配置文件中的URL协议
 *
 * @return {String}
 */
export function getSchemeHost() {
  const protocol = window.location.protocol
  const host = process.env.VITE_APP_API_HOST
  return host.replace(/scheme/g, protocol)
}

/**
 * 递归查询树节点
 *
 * @param {object} treeData 树结构数据集合
 * @param {string} prop 属性字段
 * @param {string} propValue 属性对应的值
 * @return {object} 节点对象
 */
export function recursion(tree, prop, propValue) {
  if (!tree || !Array.isArray(tree)) return false
  let result = {}

  function handelTree(tree) {
    if (!tree || !Array.isArray(tree)) return false
    let result = {}

    function handelTree(tree) {
      for (let o of tree) {
        if (o.children && Array.isArray(o.children) && o.children.length) {
          if (o[prop] !== propValue) {
            // 递归
            handelTree(o.children)
          } else {
            result = o
            break
          }
        } else {
          const reg = new RegExp(propValue, 'i')
          if (reg.test(o[prop])) {
            result = o
          }
        }
      }
      return result
    }

    return handelTree(tree)
  }

  return handelTree(tree)
}
export function searchTree(tree, prop, propValue) {
  if (!tree || !Array.isArray(tree)) return false

  const reg = new RegExp(propValue, 'i')
  let result = []
  function handelTree(tree) {
    for (let o of tree) {
      if (o.children && Array.isArray(o.children) && o.children.length) {
        if (!reg.test(o[prop])) {
          // 递归
          handelTree(o.children)
        } else {
          result.push(o)
        }
      } else {
        if (reg.test(o[prop])) {
          result.push(o)
        }
      }
    }
    return result
  }
  return handelTree(tree)
}

export function success(msg = $CONST.MSG_SYS_SUCCESS) {
  ElMessage({
    message: msg,
    type: 'success',
  })
}

export function fail(msg = $CONST.MSG_SYS_FAIL) {
  ElMessage({
    message: msg,
    type: 'error',
  })
}

export function error(msg = $CONST.MSG_SYS_ERR) {
  ElMessage({
    message: msg,
    type: 'error',
  })
}

export function warning(msg = $CONST.MSG_SYS_WARNING) {
  ElMessage({
    message: msg,
    type: 'warning',
  })
}

export function info(msg = $CONST.MSG_SYS_CANCELED) {
  ElMessage({
    message: msg,
    type: 'info',
  })
}

export function alertError(msg = $CONST.MSG_SYS_ERR, options) {
  options = Object.assign(
    {
      dangerouslyUseHTMLString: true,
      title: '提示',
      type: 'error',
      'show-icon': true,
    },
    options
  )
  vm.$alert(msg, options)
}

export function alertWarning(msg = $CONST.MSG_SYS_WARNING, options) {
  options = Object.assign(
    {
      dangerouslyUseHTMLString: true,
      title: '提示',
      type: 'warning',
      'show-icon': true,
    },
    options
  )
  vm.$alert(msg, options)
}

export function todo() {
  warning('开发中。。。')
}

/**
 * 异步加载组件
 * @author TJ 2019/05/30
 */

/* eslint-disable */
export function lazyLoadView(AsyncView) {
  const AsyncComponent = () => ({
    // 需要加载的组件 (应该是一个 `Promise` 对象)
    component: AsyncView,
    // 异步组件加载时使用的组件
    loading: '',
    // 加载失败时使用的组件
    error: '',
    // 展示加载时组件的延时时间。默认值是 200 (毫秒)
    delay: 200,
    // 如果提供了超时时间且组件加载也超时了，
    // 则使用加载失败时使用的组件。默认值是：`Infinity`
    timeout: 3000,
  })

  return Promise.resolve({
    functional: true,
    render(h, { data, children }) {
      // Transparently pass any props or children
      // to the view component.
      return h(AsyncComponent, data, children)
    },
  })
}

// 去除字符串中所有字母
export const delABC = (str) => {
  let result
  let reg = /[a-zA-Z]+/ // [a-zA-Z]表示匹配字母，g表示全局匹配
  while ((result = str.match(reg))) {
    // 判断str.match(reg)是否没有字母了
    str = str.replace(result[0], '') // 替换掉字母  result[0] 是 str.match(reg)匹配到的字母
  }
  return str
}

// 去除字符串中所有空格 去除空格
export const delBlank = (str) => {
  let result
  let reg = /\s/ // [a-zA-Z]表示匹配字母，g表示全局匹配
  while ((result = str.match(reg))) {
    // 判断str.match(reg)是否没有字母了
    str = str.replace(result[0], '') // 替换掉字母  result[0] 是 str.match(reg)匹配到的字母
  }
  return str
}

// 去除字符串中所有" 去除引号
export const delVirgule = (str) => {
  let result
  let reg = /"/g // [a-zA-Z]表示匹配字母，g表示全局匹配
  while ((result = str.match(reg))) {
    // 判断str.match(reg)是否没有字母了
    str = str.replace(result[0], '') // 替换掉字母  result[0] 是 str.match(reg)匹配到的字母
  }
  return str
}

// excel表格下载

export const tableDownload = (id, title = 'sheet') => {
  /* generate workbook object from table */
  // 判断要导出的节点中是否有fixed的表格，如果有，转换excel时先将该dom移除，然后append回去，
  let fix = document.querySelector('.el-table__fixed')
  let wb
  if (fix) {
    wb = XLSX.utils.table_to_book(
      document.getElementById(id).removeChild(fix),
      { raw: true }
    )
    document.getElementById(id).appendChild(fix)
  } else {
    wb = XLSX.utils.table_to_book(document.getElementById(id), { raw: true })
  }
  /* get binary string as output */
  let wbout = XLSX.write(wb, {
    bookType: 'xlsx',
    bookSST: true,
    type: 'array',
  })
  try {
    FileSaver.saveAs(
      new Blob([wbout], {
        type: 'application/octet-stream',
      }),
      `${title}.xlsx`
    )
  } catch (e) {
    if (typeof console !== 'undefined') console.log(e, wbout)
  }
  return wbout
}

// JSON数据下载
export const JSONTableDownload = (
  fileName,
  tHeader,
  filterVal,
  list,
  bookType
) => {
  try {
    let formatJson = (filterVal, jsonData) => {
      return jsonData.map((v) => filterVal.map((j) => v[j]))
    }
    import('./Export2Excel').then((excel) => {
      const data = formatJson(filterVal, list)
      excel.export_json_to_excel({
        header: tHeader,
        data,
        filename: fileName,
        bookType: bookType,
      })
    })
  } catch (e) {
    ElMessage.error('error')
  }
}

// 获取表格高度
export const getTableHeight = (dom, minor = 0) => {
  try {
    const pagination = 200
    const pageWrapperHeight = dom.offsetHeight
    let result = pageWrapperHeight - pagination - minor
    if (result < 100) {
      result = 100
    }
    return result
  } catch (e) {
    return ''
  }
}

// 数组对象搜索
export const zcJsonSearch = (arr, key, keyword) => {
  const zcResult = arr.filter((item) => {
    return item[key] === keyword
  })
  if (zcResult[0]) {
    return zcResult
  } else {
    return '无匹配'
  }
}

// 模糊搜索
export const zcFuzzyQueryA = (arr, conditionObj) => {
  const filterFun = (key, keyword) => {
    const arrPre = []
    const reg = new RegExp(keyword, 'i') // i不区分大小写
    for (let i = 0; i < arr.length; i++) {
      if (reg.test(arr[i][key])) {
        arrPre.push(arr[i])
      }
    }
    arr = arrPre
  }
  for (const item in conditionObj) {
    filterFun(item, conditionObj[item])
  }
  return arr
}

export const zcFuzzyQueryB = (value, key, keyword) => {
  const reg = new RegExp(keyword, 'i') // i不区分大小写
  const arr = []
  const index = []
  if (value[key]) {
    for (let i = 0; i < value.length; i++) {
      if (reg.test(value[i][key])) {
        arr.push(value[i])
        index.push(i)
      }
    }
  } else {
    return 'error'
  }
  return { arr: arr, index: index }
}
export const zcFuzzyQueryC = (arr, key, keyword) => {
  const reg = new RegExp(keyword, 'i') // i不区分大小写
  return arr.filter((item) => {
    return reg.test(item[key])
  })
}
// 翻转字符串
export const zcStringReverse = (value) => {
  return value.split('').reverse().join('')
}

// 判断IOS安卓
export const zcMobileDevice = () => {
  const u = navigator.userAgent
  const isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1 // android终端
  const isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/) // ios终端
  if (isAndroid) {
    return 'android'
  }
  if (isiOS) {
    return 'ios'
  }
}

// 基础数组对象排序
export const zcJsonCompare = (value, key) => {
  value.sort((a, b) => {
    const x1 = a[key]
    const x2 = b[key]
    if (x1 < x2) {
      return -1
    }
    if (x1 > x2) {
      return 1
    }
    return 0
  })
}

// 数组对象数字排序
export const zcJsonCompareNumber = (value, key) => {
  value.sort((a, b) => {
    const x1 = parseFloat(a[key])
    const x2 = parseFloat(b[key])
    if (x1 < x2) {
      return -1
    }
    if (x1 > x2) {
      return 1
    }
    return 0
  })
}

// 数组对象日期排序
export const zcJsonCompareDate = (value, key) => {
  value.sort((a, b) => {
    const x1 = parseFloat(dayjs(a[key]).format('YYYYMMDDHHmmss'))
    const x2 = parseFloat(dayjs(b[key]).format('YYYYMMDDHHmmss'))
    if (x1 < x2) {
      return -1
    }
    if (x1 > x2) {
      return 1
    }
    return 0
  })
}
// 数组对象文字排序
export const zcJsonWordCompare = (value, key) => {
  value.sort((a, b) => {
    const x1 = a[key].toUpperCase()
    const x2 = b[key].toUpperCase()
    if (x1 < x2) {
      return -1
    }
    if (x1 > x2) {
      return 1
    }
    return 0
  })
}

// 数字排序
export const zcNumberCompare = (value) => {
  const myCompare = function (a, b) {
    if (a < b) {
      return -1
    }
    if (a > b) {
      return 1
    }
    return 0
  }
  value.sort(myCompare)
}

// 汉字排序
export const zcChSort = (arr) => {
  arr.sort((a, b) => a.localeCompare(b))
}

// 忽略大小写排序
export const ignoreUpperSort = (arr) => {
  arr.sort((a, b) => {
    const x1 = a.toUpperCase()
    const x2 = b.toUpperCase()
    if (x1 < x2) {
      return -1
    }
    if (x1 > x2) {
      return 1
    }
    return 0
  }) // ['apple', 'Google', 'Microsoft']
}

// ****数组对象map排序****
export const zcJsonMapCompare = (value, key, mapArr) => {
  let map = { ...mapArr }
  value.sort((a, b) => {
    const x1 = a[key]
    const x2 = b[key]
    if (map[x1] < map[x2]) {
      return -1
    }
    if (map[x1] > map[x2]) {
      return 1
    }
    return 0
  })
}

// JSON 数字属性求和
export const zcJsonSum = (value, key) => {
  const preArr = []
  value.forEach((a, i, n) => {
    preArr.push(a[key])
  })
  return preArr.reduce((prev, cur) => {
    return prev + cur
  })
}

// 数组去重
export const zcQuchong = (value) => {
  return [...new Set(value)]
}

// 获取时间范围内所有日期数组
export const zcDateArr = (begin, end) => {
  const datetimeparse = (timestamp, format, prefix) => {
    if (typeof timestamp === 'string') {
      timestamp = Number(timestamp)
    }
    // 转换时区
    const currentZoneTime = new Date(timestamp)
    let currentTimestamp = currentZoneTime.getTime()
    const offsetZone = currentZoneTime.getTimezoneOffset() / 60 // 如果offsetZone>0是西区，西区晚
    let offset = null
    // 客户端时间与服务器时间保持一致，固定北京时间东八区。
    offset = offsetZone + 8
    currentTimestamp = currentTimestamp + offset * 3600 * 1000

    let newtimestamp = null
    if (currentTimestamp) {
      if (currentTimestamp.toString().length === 13) {
        newtimestamp = currentTimestamp.toString()
      } else if (currentTimestamp.toString().length === 10) {
        newtimestamp = currentTimestamp + '000'
      } else {
        newtimestamp = null
      }
    } else {
      newtimestamp = null
    }
    const dateobj = newtimestamp ? new Date(parseInt(newtimestamp)) : new Date()
    const YYYY = dateobj.getFullYear()
    const MM =
      dateobj.getMonth() > 8
        ? dateobj.getMonth() + 1
        : '0' + (dateobj.getMonth() + 1)
    const DD =
      dateobj.getDate() > 9 ? dateobj.getDate() : '0' + dateobj.getDate()
    const HH =
      dateobj.getHours() > 9 ? dateobj.getHours() : '0' + dateobj.getHours()
    const mm =
      dateobj.getMinutes() > 9
        ? dateobj.getMinutes()
        : '0' + dateobj.getMinutes()
    const ss =
      dateobj.getSeconds() > 9
        ? dateobj.getSeconds()
        : '0' + dateobj.getSeconds()
    let output = ''
    let separator = '/'
    if (format) {
      separator = format.match(/-/) ? '-' : '/'
      output += format.match(/yy/i) ? YYYY : ''
      output += format.match(/MM/) ? (output.length ? separator : '') + MM : ''
      output += format.match(/dd/i) ? (output.length ? separator : '') + DD : ''
      output += format.match(/hh/i) ? (output.length ? ' ' : '') + HH : ''
      output += format.match(/mm/) ? (output.length ? ':' : '') + mm : ''
      output += format.match(/ss/i) ? (output.length ? ':' : '') + ss : ''
    } else {
      output += YYYY + separator + MM + separator + DD
    }
    output = prefix ? prefix + output : output

    return newtimestamp ? output : ''
  }
  const arr1 = begin.split('-')
  const arr2 = end.split('-')
  const arr1_ = new Date()
  const arrTime = []
  arr1_.setUTCFullYear(arr1[0], arr1[1] - 1, arr1[2])
  const arr2_ = new Date()
  arr2_.setUTCFullYear(arr2[0], arr2[1] - 1, arr2[2])
  const unixDb = arr1_.getTime()
  const unixDe = arr2_.getTime()
  for (let k = unixDb; k <= unixDe; ) {
    arrTime.push(datetimeparse(k, 'yyyy-MM-DD'))
    k = k + 24 * 60 * 60 * 1000
  }
  return arrTime
}

// 返回指定范围内的随机整数
export const uniform = (lo, hi) => {
  return Math.floor(Math.random() * (hi - lo) + lo)
}

// 返回指定范围内的随机小数
export const randomDot = (lo, hi) => {
  return Math.random() * (hi - lo) + lo
}

// 清空对象
export const zcClearObj = (value) => {
  // eslint-disable-next-line no-return-assign
  // Object.keys(value).forEach((key) => value[key] = '')
  for (const i in value) {
    value[i] = ''
  }
}

// 时间戳转换成日期
export const timestempToTime = (value) => {
  const date = new Date(value) // 时间戳为10位需*1000，时间戳为13位的话不需乘1000
  const Y = date.getFullYear() + '-'
  const M =
    (date.getMonth() + 1 < 10
      ? '0' + (date.getMonth() + 1)
      : date.getMonth() + 1) + '-'
  const D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ''
  const h =
    (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':'
  const m =
    (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + ':'
  const s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
  return Y + M + D + ' ' + h + m + s
}

// 基础深拷贝
export const cloneDeep = (obj) => {
  const res = obj.constructor === Array ? [] : {}
  for (const [k, v] of Object.entries(obj)) {
    // 解构对象键值对
    res[k] = typeof v === 'object' ? cloneDeep(v) : v
  }
  return res
}
// 深拷贝加条件，能转成数字的字符串转成数字
export const zcFilter = (
  data = [],
  notTrans = '',
  numDot = 2,
  type = 'string'
) => {
  if (data === null) {
    return '--'
  } else {
    const result = data.constructor === Array ? [] : {}
    for (const [key, value] of Object.entries(data)) {
      if (typeof value === 'object' && !_.isNull(value)) {
        result[key] = zcFilter(value, notTrans, numDot, type)
      } else {
        if (
          typeof value === 'string' &&
          !isNaN(Number(value)) &&
          key !== notTrans
        ) {
          result[key] =
            type === 'string'
              ? parseFloat(value).toFixed(numDot)
              : _.round(value, numDot)
        } else {
          if (typeof value === 'number' && key !== notTrans) {
            result[key] =
              type === 'string'
                ? parseFloat(value).toFixed(numDot)
                : _.round(value, numDot)
          } else {
            if (_.isNull(value)) {
              result[key] = 'null'
            } else {
              result[key] = value // 做null 转换
            }
          }
        }
      }
    }
    return result
  }
}

export const zcFilterMutiNotTrans = (
  data = [],
  notTrans = [],
  numDot = 2,
  type = 'string'
) => {
  if (data === null) {
    return '--'
  } else {
    const result = data.constructor === Array ? [] : {}
    for (const [key, value] of Object.entries(data)) {
      if (typeof value === 'object' && !_.isNull(value)) {
        result[key] = zcFilterMutiNotTrans(value, notTrans, numDot, type)
      } else {
        if (
          typeof value === 'string' &&
          !isNaN(Number(value)) &&
          !notTrans.includes(key)
        ) {
          result[key] =
            type === 'string'
              ? parseFloat(value).toFixed(numDot)
              : _.round(value, numDot)
        } else {
          if (typeof value === 'number' && !notTrans.includes(key)) {
            result[key] =
              type === 'string'
                ? parseFloat(value).toFixed(numDot)
                : _.round(value, numDot)
          } else {
            if (_.isNull(value)) {
              result[key] = 'null'
            } else {
              result[key] = value // 做null 转换
            }
          }
        }
      }
    }
    return result
  }
}

export const zcBaseSearchFontColor = () => {
  try {
    let domList = document.getElementsByClassName('el-form-item__label')
    for (let item of domList) {
      item.style.color = getLocal('dintTheme')
    }
  } catch (e) {
    this.$message.error('dom render failure')
  }
}

// 测试用的数据origin Data
// [{a: 1, b: 2},
//  {a: 1, b: 2},
//  {a: 2, b: 3}]
// result
// [{a: 1, b: 4}
// {a: 2, b: 3}]
// 合并JSON同类项的数字属性
export const zcSumSame = (data, key, numKey = []) => {
  const dataPre = []
  for (let i = 0; i < data.length; i++) {
    const isExist = dataPre.filter((itemPre) => itemPre[key] === data[i][key])
    if (isExist.length > 0) {
      for (const item of numKey) {
        isExist[0][item] += data[i][item]
      }
    } else {
      dataPre.push(data[i])
    }
  }
  return dataPre
}

// data [1, 2, 3, 4, 5, 6, 7, 8, 9]
// result [[1, 2, 3, 4], [5, 6, 7, 8], [9]]
export const fourClassification = (data, num) => {
  let counter = 0
  let arrIndex = 0
  const preArr = []
  for (let i = 0; i < data.length; i++) {
    if (!preArr[arrIndex]) preArr[arrIndex] = []
    preArr[arrIndex].push(data[i])
    counter++
    if (counter === num) {
      arrIndex++
      counter = 0
    }
  }
  return preArr
}

// 判断回文
export const isPalindrome = (s) => {
  const n = s.length
  for (let i = 0; i < n / 2; i++) {
    // 循环字符串长度的一半
    // chartAt(i)返回第i个字符
    if (s.charAt(i) !== s.charAt(n - 1 - i)) {
      // 判断首尾字符是否相等
      return false // 不等返回false
    }
  }
  return true // 全部相等返回true
}

// 判断文件类型
export const getFileType = (fullName) => {
  const dot = fullName.indexOf('.')
  const fileName = fullName.substr(0, dot)
  const fileType = fullName.substr(dot + 1, fullName.length)
  return {
    fileName: fileName,
    fileType: fileType,
  }
}

// 打乱一个数组
export const shuffle = (arr) => {
  const n = arr.length
  for (let i = 0; i < n; i++) {
    const r = i + Math.floor(Math.random() * (n - i))
    const temp = arr[i]
    arr[i] = arr[r]
    arr[r] = temp
  }
}

// 打乱数组进阶版
export const shuffleArr = (arr) => {
  arr.sort(() => 0.5 - Math.random())
}

// 生成范围内整数数组
export const generateArray = (start, end) => {
  return Array.from(new Array(end + 1).keys()).slice(start)
}

// 页面跳转到指定位置
export const pageAutoJump = (dom, top) => {
  // let dot = document.getElementsByClassName('incentive-title')[index + 1]
  // document.getElementsByClassName('page-content')[0].
  dom.scroll({
    top: top,
    left: 0,
    behavior: 'smooth',
  })
}

// 空值返回默认值
export const formatBlankString = (string) => {
  try {
    if (isTrue(string)) {
      return string
    } else {
      return '--'
    }
  } catch (e) {
    console.log(e)
    return '--'
  }
}

export const getFontMaxWidth = (maxWord) => {
  // 创建textArea
  // 测试 span标签
  if (this.$T.isTrue(maxWord)) {
    let maxWidthSpan = document.createElement('span')
    let id = _.uniqueId('tableHeader')
    maxWidthSpan.textContent = maxWord
    maxWidthSpan.id = id + 'maxWord-span'
    maxWidthSpan.style.opacity = 0
    maxWidthSpan.style.position = 'fixed'
    document.body.appendChild(maxWidthSpan)
    setTimeout(() => {
      document.body.removeChild(maxWidthSpan) // 获取宽度后完成移除元素
    }, 3000)
    let result = maxWidthSpan.offsetWidth + 20
    if (result > 200) {
      return 200
    } else if (result < 90) {
      return 90
    } else {
      return result
    }
  } else {
    return 150
  }
}

// 自动获取最大表格宽度
export const autoColumnWidth = (tableData, key) => {
  let columnName = key
  if (tableData.length > 0) {
    let maxWordLength = 0
    let maxWord = ''
    for (let item of tableData) {
      if (item[columnName].length > maxWordLength) {
        maxWordLength = item[columnName].length
        maxWord = item[columnName]
      }
    }
    try {
      return getFontMaxWidth(maxWord)
    } catch (e) {
      return ''
    }
  }
}

// ----------------------抛硬币第一天-------------------------------
// 返回按照指定几率 返回true/false (抛硬币)
export const RandomBernoulli = (key) => {
  if (typeof key === 'number' && key >= 0 && key <= 1) {
    return Math.random() >= key // Math.Random() 方法中随即返回0-1之间的小数，若超过则返回true 否则返回false
  } else {
    return '无效值'
  }
}

// 计数器类
export class Counter {
  count = 0

  constructor(name) {
    this.name = name
  }

  increment = () => {
    this.count++
  }
  tally = () => {
    return this.count
  }
  toString = () => {
    return this.count.toString()
  }
}

// 抛硬币类
export class Flips {
  constructor(name) {
    this.name = name
  }

  main(args) {
    const T = parseInt(args[0])
    const heads = new Counter('heads')
    const tails = new Counter('tails')
    for (let t = 0; t < T; t++) {
      if (RandomBernoulli(0.5)) {
        heads.increment()
      } else {
        tails.increment()
      }
    }
    const d = heads.tally() - tails.tally()
    return {
      heads: heads,
      tails: tails,
      delta: Math.abs(d), // 绝对值
    }
  }
}

// ------------------------抛硬币第二天--------------------------------
export const FlipMax = (x, y) => {
  const xt = x.tally()
  const yt = y.tally()
  if (xt > yt) {
    return {
      name: x.name,
      xTally: xt,
      yTally: yt,
    }
  } else {
    return {
      name: y.name,
      xTally: xt,
      yTally: yt,
    }
  }
}

// 猜正反
export class FlipWin {
  constructor(name) {
    this.name = name
  }

  main(arr) {
    const T = parseInt(arr[0])
    const heads = new Counter('heads')
    const tails = new Counter('tails')
    for (let t = 0; t < T; t++) {
      if (RandomBernoulli(0.5)) {
        // 如果返回为true 正面加1
        heads.increment()
      } else {
        tails.increment()
      }
    }
    if (heads.tally() === tails.tally()) {
      return {
        name: 'Both',
        xTally: T / 2,
        yTally: T / 2,
      }
    } else {
      return FlipMax(heads, tails)
    }
  }
}

// -------------抛硬币的第二天开始了掷色子。。。----------
export class Rolls {
  constructor(name) {
    this.name = name
  }

  main(arr, SIDES) {
    const T = parseInt(arr[0]) // 摇色子的次数
    const rolls = [] // 装筛子面次数的容器
    for (let item of SIDES) {
      rolls.push(new Counter(item)) // 将6个面的计数器对象填入数组中
    }
    for (let t = 0; t < T; t++) {
      let result = uniform(0, 6) + '' // 从1-6中随机取一个key
      try {
        rolls[result].increment() // 摇到了面对应的面+1
      } catch (e) {
        console.log(result)
      }
    }
    const result = [] // 声明结果
    for (let i in SIDES) {
      result.push(rolls[i]) // 将rolls拷贝到结果中
    }
    let max = 0
    result.forEach((item) => {
      let a = parseInt(item.count)
      if (a > max) max = a
    })
    return [result, max] // 返回结果
  }
}

// ------------------抽象数据类型学习第三天-------------------------

// ---------------------reduce-----------------------
// 计算数组中每一个元素出现的次数
export const arrCount = (arr) => {
  return arr.reduce((prev, cur) => {
    if (cur in prev) {
      // 如果当前项在前一项中，前一项增加1
      prev[cur]++
    } else {
      prev[cur] = 1
    }
    return prev // {key: number} 该返回值为一个数组值次数统计的结构
  }, {})
}

// 对象数组去重
export const objArrDuplicate = (arr, key) => {
  const newObj = {}
  arr = arr.reduce((preVal, curVal) => {
    // eslint-disable-next-line no-unused-expressions
    newObj[curVal[key]] ? '' : (newObj[curVal[key]] = preVal.push(curVal))
    return preVal
  }, [])
  return arr
}
// 数组扁平化
export const myFlat = (arr) => {
  return arr.reduce((prev, cur) => {
    return prev.concat(Array.isArray(cur) ? myFlat(cur) : cur)
  }, [])
}

// 对象数组分类
export const objArrGroupBy = (objArr, keyWord) => {
  return objArr.reduce((acc, cur) => {
    const key = cur[keyWord]
    if (!acc[key]) {
      acc[key] = [] // 初始化返回值
    }
    acc[key].push(cur)
    return acc // 每次迭代都将相同的值 push进相同的属性中
  }, {})
}

// 数组对象中的数组合并(不去重)
export const objArrMerge = (objArr, keyWord) => {
  return objArr.reduce((prev, cur) => {
    return [...prev, ...cur[keyWord]]
  }, [])
}

// 数组去重
export const arrDuplicate = (arr) => {
  return arr.reduce((prev, cur) => {
    if (prev.indexOf(cur) === -1) {
      prev.push(cur)
    }
    return prev
  }, [])
}

export const openNewTag = (url) => {
  window.open(url, '_blank')
}

export const getHeaderClass = () => {
  let themeColor = getLocal('dintTheme')
  return `background: ${themeColor};color:white`
}

// 智能城市诊断
export const handleMapArr = (mapArr) => {
  return mapArr.map((a, i, n) => {
    return {
      IndicatorName: a['name'],
      TheCityItself: '',
      SimilarCities: '',
      National: '',
      VSSimilarCities: '',
      VSNational: '',
      type: a['type'],
    }
  })
}

// 智能城市诊断数据处理A
export const cityDiagnosisMappingA = (mappingTable, originData, noRate) => {
  let resultArr = []
  let ifTransK = (value) => {
    return value > 1000 ? _.round(value, 0).toLocaleString() : value
  }
  mappingTable.forEach((a, i, n) => {
    let name = a['IndicatorName']
    let isSimilar =
      isTrue(originData['target']['similar']) &&
      isTrue(originData['target']['similar'][name]) &&
      isTrue(originData['diff']['similar'][name])
    let isNation =
      isTrue(originData['target']['nation']) &&
      isTrue(originData['target']['nation'][name]) &&
      isTrue(originData['diff']['nation'][name])
    let tself = isTrue(originData['target']['self'][name])
      ? originData['target']['self'][name]
      : null
    let dself = isTrue(originData['diff']['self'][name])
      ? originData['diff']['self'][name]
      : null
    let tsimilar = isSimilar ? originData['target']['similar'][name] : null
    let dsimilar = isSimilar ? originData['diff']['similar'][name] : null
    let tall = isTrue(originData['target']['nation'][name])
      ? originData['target']['nation'][name]
      : null
    let dall = isTrue(originData['diff']['nation'][name])
      ? originData['diff']['nation'][name]
      : null
    let valueObj = {}
    let handleRate = (a, b, needRate) => {
      let result = ((a / b - 1) * 100).toFixed(2)
      if (isNaN(result) || result.indexOf('Infinity') > -1) {
        return '--'
      } else {
        return needRate ? result + '%' : result
      }
    }
    if (a['type'] === 'value') {
      // 目标值对象处理
      let ifTransKB = () => {
        return tself <= 1000
      }
      valueObj['IndicatorName'] = vm.$t(`index.${name}`)
      valueObj['TheCityItself'] = ifTransK(tself)
      valueObj['SimilarCities'] = ifTransK(tsimilar)
      valueObj['National'] = ifTransK(tall)
      let vvsc = handleRate(tself, tsimilar)
      valueObj['VSSimilarCities'] =
        isSimilar && !isNaN(Number(vvsc)) && ifTransKB() ? vvsc + '%' : '--'
      let vvsn = handleRate(tself, tall)
      valueObj['VSNational'] =
        isNation && !isNaN(Number(vvsn)) && ifTransKB() ? vvsn + '%' : '--'
      // 增速对象处理 // 外加 vs差值计算 目标月/对比月 + 1 target, diff
      // 如果对比月不是%字符串类型则需要计算
      let rateObj = {}
      rateObj['IndicatorName'] = '△' + vm.$t(`index.${name}`)
      rateObj['TheCityItself'] = handleRate(tself, dself, true)
      rateObj['SimilarCities'] = handleRate(tsimilar, dsimilar, true)
      rateObj['National'] = handleRate(tall, dall, true)
      let rvsc = (
        handleRate(tself, dself) - handleRate(tsimilar, dsimilar)
      ).toFixed(2)
      rateObj['VSSimilarCities'] =
        isSimilar && !isNaN(rvsc) ? rvsc + ' pp' : '--'
      let rvsn = (handleRate(tself, dself) - handleRate(tall, dall)).toFixed(2)
      rateObj['VSNational'] = isNation && !isNaN(rvsn) ? rvsn + ' pp' : '--'
      resultArr.push(valueObj)
      if (!noRate) {
        resultArr.push(rateObj)
      }
    } else {
      // 目标值对象处理
      let toRate = (value) => {
        if (!isNaN(Number(value))) {
          return (value * 100).toFixed(2) + '%'
        } else {
          return '--'
        }
      }
      let toRateB = (value) => {
        if (!isNaN(Number(value))) {
          return (value * 100).toFixed(2) + ' pp'
        } else {
          return '--'
        }
      }
      valueObj['IndicatorName'] = vm.$t(`index.${name}`)
      valueObj['TheCityItself'] = toRate(tself)
      valueObj['SimilarCities'] = isSimilar ? toRate(tsimilar) : '--'
      valueObj['National'] = toRate(tall)
      let vvsc = ((tself - tsimilar) * 100).toFixed(2)
      valueObj['VSSimilarCities'] = isSimilar ? vvsc + ' pp' : '--'
      let vvsn = ((tself - tall) * 100).toFixed(2)
      valueObj['VSNational'] = isNation ? vvsn + ' pp' : '--'
      // 增速对象处理 // 外加 vs差值计算 目标月/对比月 + 1 target, diff
      // 如果对比月不是%字符串类型则需要计算
      let rateObj = {}
      rateObj['IndicatorName'] = '△' + vm.$t(`index.${name}`)
      rateObj['TheCityItself'] = toRateB(tself - dself)
      rateObj['SimilarCities'] = isSimilar ? toRateB(tsimilar - dsimilar) : '--'
      rateObj['National'] = toRateB(tall - dall)
      let rvsc = tself - dself - (tsimilar - dsimilar)
      rateObj['VSSimilarCities'] =
        isSimilar && !isNaN(rvsc) ? toRateB(rvsc) : '--'
      let rvsn = tself - dself - (tall - dall)
      rateObj['VSNational'] = isNation && !isNaN(rvsn) ? toRateB(rvsn) : '--'
      resultArr.push(valueObj)
      if (!noRate) {
        resultArr.push(rateObj)
      }
    }
  })
  return resultArr
}

export const getNormalHeaderClass = (color) => {
  return { color: color }
}

export const handleWeek = (val) => {
  let date = vm.$dayjs(val).format('YYYY-MM-DD')
  let w
  if (!isNaN(vm.$dayjs(date).week())) {
    let firstDayOfYear = vm.$dayjs(date).format('YYYY-01-01')
    if (vm.$dayjs(firstDayOfYear).day() >= 5) {
      w = vm.$dayjs(date).week() - 1
    } else {
      w = vm.$dayjs(date).week()
    }
  } else {
    w = ''
  }
  return w
}
export const getLegoCityName = (cityCode) => {
  try {
    let myList = _.cloneDeep(vm.$store.state.lego.cityList)
    myList.unshift({ cityid: 'all', city_name_en: 'All' })
    return myList.filter((item) => item.cityid == cityCode)[0]['city_name_en']
  } catch (e) {
    return '--'
  }
}
export const handleCityDiagnosisChartLine = (
  renderList,
  originData,
  endYear,
  sortArr
) => {
  let valueTypeList = []
  for (let [k, v] of Object.entries($CONST.diagnosisMapPOP)) {
    valueTypeList = valueTypeList.concat(v)
  }
  let getUnit = (e) => {
    let result = ''
    let itemObj = valueTypeList.filter((item) => item.name === e)
    if (itemObj.length > 0) {
      result = itemObj[0].type === 'rate' ? '%' : ''
    }
    return result
  }
  let result = []
  for (let item of renderList) {
    let series = []
    let xData = []
    let yAxis = []
    let index = -1
    let singleList = [
      // 需要单轴的指标
      'gmv_pop',
      'eyeballs_pop',
      'calls_pop',
      'rides_pop',
      'tsh',
      'online_drivers',
    ]
    let isSingle = !singleList.includes(item)
    let xDataCity = sortArr[0]
    let getMarkData = () => {
      let markData = []
      let myIndex = null
      for (let i = 1; i < xData.length; i++) {
        if (xData[i] && xData[i].split('-')[0] !== xData[i - 1].split('-')[0]) {
          myIndex = i
        }
      }
      if (isTrue(myIndex)) {
        markData = [
          [
            {
              name: endYear,
              xAxis: xData[myIndex],
            },
            {
              xAxis: xData[xData.length - 1],
            },
          ],
        ]
      }
      return markData
    }
    for (let k of sortArr) {
      // 根据指定顺序渲染趋势图
      if (originData[k]) {
        index++
        // 选择城市
        if (originData[k].length >= originData[xDataCity].length) {
          xDataCity = k
        }
        if (!isSingle) {
          yAxis.push({
            z: index,
            type: 'value',
            min: function (value) {
              if (value.min < 1) {
                return value.min
              } else {
                return parseInt(value.min - value.min / 2)
              }
            },
            axisLabel: {
              formatter: '{value}' + getUnit(item),
            },
            axisPointer: {
              snap: true,
            },
          })
        } else {
          yAxis = [
            {
              type: 'value',
              min: function (value) {
                if (value.min < 1) {
                  return value.min
                } else {
                  return parseInt(value.min - value.min / 2)
                }
              },
              axisPointer: {
                snap: true,
              },
              axisLabel: {
                formatter: '{value}' + getUnit(item),
              },
            },
          ]
        }
        series.push({
          name: getLegoCityName(k),
          type: 'line',
          smooth: true,
          yAxisIndex: isSingle ? 0 : index,
          data: originData[k].map((itemM) => itemM[item]),
          // markArea: {
          //   itemStyle: {
          //     color: 'rgba(215,215,215,0.1)',
          //   },
          //   data: getMarkData(),
          // },
        })
      }
    }
    // 渲染横坐标数组
    xData = originData[xDataCity].map((itemM) => {
      // 单数加0
      let zero = itemM['date_type_value'].length > 1 ? '' : '0'
      return (
        itemM['start_date'].split('-')[0] +
        '-' +
        zero +
        itemM['date_type_value']
      )
    })
    result.push({
      title: vm.$t(`index.${item}`),
      chartData: {
        series: series,
        xData: xData,
        yAxis: yAxis,
        toolTipFormatter: '{c}' + getUnit(item),
      },
    })
  }
  return result
}

// 散点图数据处理
export const handleCityDiagnosisChartDot = (
  renderList,
  originData,
  targetCityId
) => {
  let valueTypeList = []
  for (let [k, v] of Object.entries($CONST.diagnosisMapPOP)) {
    valueTypeList = valueTypeList.concat(v)
  }
  let getUnit = (e) => {
    let result = ''
    let itemObj = valueTypeList.filter((item) => item.name === e)
    if (itemObj.length > 0) {
      result = itemObj[0].type === 'rate' ? '%' : ''
    }
    return result
  }
  let result = []
  if (originData[targetCityId]) {
    for (let item of renderList) {
      let type = 'eyeballs_dsr'
      if (
        item === 'cr_gmv' ||
        item === 'cr_pop' ||
        item === 'charge_online_rate'
      ) {
        type = 'dsr'
      }
      let series = []
      for (let itemB of originData[targetCityId]) {
        let zero = itemB['date_type_value'].length > 1 ? '' : '0'
        series.push({
          name:
            itemB['start_date'].split('-')[0] +
            '-' +
            zero +
            itemB['date_type_value'], // 月份
          type: 'scatter',
          emphasis: {
            focus: 'series',
          },
          data: [[itemB[type], itemB[item]]],
        })
      }
      result.push({
        title: vm.$t(`index.${item}`),
        chartData: {
          title: vm.$t(`index.${item}`),
          originTitle: item,
          originData: originData[targetCityId],
          series: series,
          unit: getUnit(item),
        },
        type: type,
      })
    }
  }
  return result
}

export const ZCJSONParse = (originData, city_ids) => {
  try {
    let JSONPre
    if (typeof originData == 'string') {
      JSONPre = JSON.parse(originData)
    } else if (typeof originData == 'object') {
      JSONPre = originData
    } else {
      ElMessage.error('json msg error!')
    }
    if (JSONPre['customize-params']) {
      let strPre = JSONPre['customize-params'].replace(
        new RegExp('\\"', 'gm'),
        '"'
      )
      let preObj
      try {
        preObj = JSON.parse(strPre.substring(1, strPre.length - 1))
      } catch {
        preObj = JSON.parse(strPre)
      }
      if (preObj.constructor === Object) {
        preObj['city_ids'] = city_ids
        JSONPre['customize-params'] = JSON.stringify(preObj)
      } else {
        let preObj = {
          city_ids: city_ids,
        }
        JSONPre['customize-params'] = JSON.stringify(preObj)
        ElMessage.warning(
          'customize-params is empty, already input default customize-params'
        )
      }
    } else {
      let preObj = {
        city_ids: city_ids,
      }
      JSONPre['customize-params'] = JSON.stringify(preObj)
      ElMessage.warning(
        'customize-params is empty, already input default customize-params'
      )
      // ElMessage.error(`json msg must have 'customize-params'`)
      // return
    }
    return JSONPre
  } catch (e) {
    return false
  }
}

export const uuid = (len, radix) => {
  //8, 16
  var chars =
    '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
  var uuid = [],
    i
  radix = radix || chars.length

  if (len) {
    // Compact form
    for (i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)]
  } else {
    // rfc4122, version 4 form
    var r

    // rfc4122 requires these characters
    uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
    uuid[14] = '4'

    // Fill in random data.  At i==19 set the high bits of clock sequence as
    // per rfc4122, sec. 4.1.5
    for (i = 0; i < 36; i++) {
      if (!uuid[i]) {
        r = 0 | (Math.random() * 16)
        uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r]
      }
    }
  }

  return uuid.join('')
}
